#include"Common.hpp"

#include<cstring>
namespace FangZhang 
{
  class string
  {
  public:
    typedef char* iterator;
    typedef const char* const_iterator;

    string(const char* str = "")
    {
      _size = _capacity = strlen(str);
      _str = new char[_capacity + 1];
      strcpy(_str, str);
    }

    //string(const string& str)
    //  : _str(nullptr)
    //  , _size(0)
    //  , _capacity(0)
    //{
    //  string tmp(str.c_str());
    //  swap(tmp);
    //}
    
    string(const string& str)
      : _str(new char[str._capacity + 1])
      , _size(str._size)
      , _capacity(str._capacity)
    {
      strcpy(_str, str._str);
    }

    string& operator=(const string& str)
    {
      if(this != &str)
      {
        char* tmp = new char[str._capacity + 1];
        strcpy(tmp, str._str);
        delete[] _str;
        _str = tmp;
        _size = str._size;
        _capacity = str._capacity;
      }

      return *this;
    }

    void swap(string& str)
    {
      std::swap(_str, str._str);
      std::swap(_size, str._size);
      std::swap(_capacity, str._capacity);
    }

    const char* c_str()const
    {
      return _str;
    }
    
    char& operator[](const size_t pos)
    {
      assert(pos < _size);
      
      return _str[pos];
    }

    const char& operator[](const size_t pos)const
    {
      assert(pos < _size);
      
      return _str[pos];
    }

    void clear()
    {
      _str[0] = '\0';
      _size = 0;
    }

    ~string()
    {
      delete[] _str;
      _str = nullptr;
      _size = _capacity = 0;
    }

    iterator begin()
    {
      return _str;
    }

    iterator end()
    {
      return _str + _size;
    }

    const_iterator begin()const
    {
      return _str;
    }

    const_iterator end()const
    {
      return _str + _size;
    }

  private:
    char* _str;
    size_t _size;
    size_t _capacity;
  };


  std::ostream& operator<<(std::ostream& out, const string& str)
  {
    for(auto c : str)
    {
      out << c;
    }

    return out;
  }

  //std::istream& operator>>(std::istream& in, string& str)
  //{
  //  str.clear(); 
  //  
  //}


  void TestString()
  {
    string s1;
    cout << s1 << endl;

    string s2("abcd");
    cout << s2 << endl;

    string s3("vbnadswfm");
    cout << s3 << endl;

    string cp1(s3);
    cout << cp1 << endl;
    printf("%p %p\n", cp1.c_str(), s3.c_str());

    s2 = s3;
    cout << s2 << endl;
  }
}
